using System;
using System.IO;

namespace CGMSharp
{
	/// <summary>
	/// Summary description for command.
	/// </summary>
	public class Command
	{
		private int elementClass;
		private int elementID;
		private MemoryStream parameters;

		public Command()
		{
			parameters = new MemoryStream();
		}

		public Command(Stream s)
		{
			parameters = new MemoryStream();
			LoadRecord(s);
		}

		#region Properties

		public int ElementClass
		{
			get
			{
				return elementClass;
			}
			set
			{
				elementClass = value;
			}
		}

		public int ElementID
		{
			get
			{
				return elementID;
			}
			set
			{
				elementID = value;
			}
		}

		public Stream Parameters
		{
			get
			{
				return parameters;
			}
		}

		#endregion 

		public bool LoadRecord(Stream s)
		{
			int len;
			bool cont=false;
			try
			{
				int cmd = BinaryUtil.ReadWord(s);
				elementClass = cmd >> 12;
				elementID = cmd >> 5 & 0x7f;
				len = cmd & 0x1f;
				
				if(len==0x1f)
				{
					len = BinaryUtil.ReadWord(s);
					if(len>>15==1) cont=true;	 /// TODO: Handle continued commands
					len&=0x7fff;
                }

				if(len%2==1) len++;

				for(int x=0;x<len;x++) parameters.WriteByte((byte)s.ReadByte());

				parameters.Seek(0,SeekOrigin.Begin);
			}
			catch (Exception ex)
			{
				return false;
			}
			return true;
		}

		public bool WriteRecord(Stream s)
		{	
			try
			{
				int cmd = (int)((uint)elementClass << 12 | (uint)elementID << 5 | (parameters.Length >= 0x1f ? 0x1f : (uint)parameters.Length));
				
				BinaryUtil.WriteWord(s,cmd);
				
				/// TODO: handle continued commands	
				if(parameters.Length>=0x1f) BinaryUtil.WriteWord(s,(int)parameters.Length);
				
				parameters.Seek(0,SeekOrigin.Begin);

				for(int x=0;x<parameters.Length;x++) s.WriteByte((byte)parameters.ReadByte()); 
				if(parameters.Length%2==1) s.WriteByte(0);
			}
			catch (Exception ex)
			{
				return false;
			}
			return true;
		}
	}
}
